<?php

/**
 * post actions.
 *
 * @package    blogallery
 * @subpackage post
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 3335 2007-01-23 16:19:56Z fabien $
 */
class postActions extends sfActions
{
  public function executeIndex()
  {
    $c = new Criteria();
 	  $c->add(PostPeer::PUBLISHED, '1');
    
    // sorted by date by default
    $c->addAscendingOrderByColumn(PostPeer::DATETIME);
    
    $this->pager = $this->getPager($c);
  }

  public function executeShow()
  {
    $this->post = PostPeer::retrieveByHandle($this->getRequestParameter('handle'));
    $this->forward404Unless($this->post instanceof Post);
    $this->forward404Unless($this->post->getPublished());
  }
  
  public function executeTag()
  {
  	$this->tag = TagPeer::retrieveByHandle($this->getRequestParameter('tag'));
  	
    $c = new Criteria();
    
    $crit = new Criteria();
    $crit->add(TagPeer::ID, $this->tag->getId());
    $crit->addJoin(PostTagPeer::TAG_ID, TagPeer::ID, Criteria::LEFT_JOIN);
    foreach (PostTagPeer::doSelect($crit) as $post_tag)
    {
      $c->addOr($c->getNewCriterion(PostPeer::ID, $post_tag->getPostId()));
    }
    
 	  $c->add(PostPeer::PUBLISHED, '1');
    
    // sorted by date by default
    $c->addAscendingOrderByColumn(PostPeer::DATETIME);
    
    $this->pager = $this->getPager($c);
  }
  
  private function getPager($c)
  {
    $c->addJoin(PostPeer::ID, PostI18nPeer::ID);
    $c->add(PostI18nPeer::CULTURE, $this->getUser()->getCulture());
    
 	$pager = new sfPropelPager('Post', sfConfig::get('app_max_post'));
 	$pager->setCriteria($c);
    $pager->setPeerMethod('doSelectWithI18n');
    $pager->setPage($this->getRequestParameter('page', 1));
 	$pager->init();
 	
 	return $pager;
  }

// administration actions

  public function executeList()
  {
    $this->processSort();

    $this->processFilters();
    
    $this->filters = $this->getUser()->getAttributeHolder()->getAll('sf_admin/post/filters');

    // pager
    $this->pager = new sfPropelPager('Post', 20);
    $c = new Criteria();
    $this->addSortCriteria($c);
    $this->addFiltersCriteria($c);
    $this->pager->setCriteria($c);
    $this->pager->setPage($this->getRequestParameter('page', 1));
    $this->pager->init();
  }

  public function executeCreate()
  {
    return $this->forward('post', 'edit');
  }

  public function executeSave()
  {
    return $this->forward('post', 'edit');
  }

  public function executeEdit()
  {
    $this->languages = LanguagePeer::doSelect(new Criteria());    
    $this->post = $this->getPostOrCreate();

    if ($this->getRequest()->getMethod() == sfRequest::POST)
    {
      $this->updatePostFromRequest();

      // $this->savePost($this->post);

      $this->setFlash('notice', 'Your modifications have been saved');

      if ($this->getRequestParameter('save_and_add'))
      {
        return $this->redirect('@admin?module=post&action=edit');
      }
      else if ($this->getRequestParameter('save_and_list'))
      {
        return $this->redirect('@admin?module=post&action=list');
      }
      else
      {
        return $this->redirect('@admin?module=post&action=edit&id='.$this->post->getId());
      }
    }
    else
    {
      $this->labels = $this->getLabels();
    }
  }
  
  public function executeDelete()
  {
    $this->post = PostPeer::retrieveByPk($this->getRequestParameter('id'));
    $this->forward404Unless($this->post);

    try
    {
      $this->deletePost($this->post);
    }
    catch (PropelException $e)
    {
      $this->getRequest()->setError('delete', 'Could not delete the selected Post. Make sure it does not have any associated items.');
      return $this->forward('post', 'list');
    }

    return $this->redirect('@admin?module=post&action=list');
  }

  public function handleErrorEdit()
  {
    $this->preExecute();
    $this->post = $this->getPostOrCreate();
    $this->updatePostFromRequest();

    $this->labels = $this->getLabels();

    return sfView::SUCCESS;
  }

  protected function savePost($post)
  {
    $post->save();

  }

  protected function deletePost($post)
  {
    $post->delete();
  }

  protected function updatePostFromRequest()
  {
    $post = $this->getRequestParameter('post');

    if (isset($post['handle']))
    {
      $this->post->setHandle($post['handle']);
    }
    if (isset($post['datetime']))
    {
      if ($post['datetime'])
      {
        try
        {
          $dateFormat = new sfDateFormat($this->getUser()->getCulture());
                              if (!is_array($post['datetime']))
          {
            $value = $dateFormat->format($post['datetime'], 'i', $dateFormat->getInputPattern('d'));
          }
          else
          {
            $value_array = $post['datetime'];
            $value = $value_array['year'].'-'.$value_array['month'].'-'.$value_array['day'].(isset($value_array['hour']) ? ' '.$value_array['hour'].':'.$value_array['minute'].(isset($value_array['second']) ? ':'.$value_array['second'] : '') : '');
          }
          $this->post->setDatetime($value);
        }
        catch (sfException $e)
        {
          // not a date
        }
      }
      else
      {
        $this->post->setDatetime(null);
      }
    }
    if (isset($post['published']))
    {
      $this->post->setPublished($post['published']);
    }  
    
    $this->savePost($this->post);
    
    if (isset($post['images']))
    {
      $this->setImages($post['images']);
    }
    if (isset($post['i18n']))
    {
      $this->seti18n($post['i18n']);
    }
    if (isset($post['tags']))
    {
      $this->setTags($post['tags']);
    }
  }
  
  protected function setImages($images)
  {
    //set images
    foreach($images as $n => $img)
    {
      $image = ImagePeer::retrieveByPostIdAndPk($this->post->getId(), $img['id']);
      if($img['delete'])
      {
        $this->deleteImages($image->getFileName());
        $image->delete();
        continue;
      }
      
      if(!$image instanceof Image)
      {
        $image = new Image();
        $image->setPostId($this->post->getId());
        $image->save();
      }
      
      $fn = $this->handleUpload('file_'.$n, $image->getId());
      $file_name = $fn ? $fn : $image->getFileName();
      
      $image->setFileName($file_name);      
      $image->setDatetime($img['datetime']);
      $image->save();
           
      foreach($img['i18n'] as $culture => $i18n)
      {
        $image_i18n = ImageI18nPeer::retrieveByPk($image->getId(), $culture);
        
        if(!$image_i18n instanceof ImageI18n)
        {
          $image_i18n = new ImageI18n();
        }
        
        $image_i18n->setImage($image);
        $image->setCulture($culture);
        $image->setCaption($i18n['caption']);
        $image->save();
        
        // if post has only one image and no title set image caption as post title
        if ((count($this->getRequestParameter('images')) === 1) and !$this->post->getTitle())
        {
          $this->post->setCulture($culture);
          $this->post->setTitle($image->getCaption());
          $this->post->save();
        }
      }        
    }
  }
  
  protected function handleUpload($param, $id)
  {
    if($this->getRequest()->getFileName($param))
    { 
      $file_name = $id.'.jpg';
    
      foreach(sfConfig::get('app_image_sizes') as $type => $sizes)
      {
        $thumb = new sfThumbnail($sizes['w'], $sizes['h']);
        $thumb->loadFile($this->getRequest()->getFilePath($param));
        $thumb->save(sfConfig::get('sf_upload_dir').'/'.$type.'_'.$file_name, 'image/jpeg');
        $thumb->freeAll();
      }
      
      return $file_name;
    }
    
    return false;  
  }
  
  protected function deleteImages($name)
  {
    foreach(sfConfig::get('app_image_sizes') as $type => $tmp)
    {
      //delete image
      $file = sfConfig::get('sf_upload_dir').'/'.$type.'_'.$name;
      if(is_file($file))
      {
        unlink($file);
      }
    }
  }
  
  protected function setI18n($i18ns)
  {
    //set i18n post fields
    foreach($i18ns as $culture => $i18n)
    {
      $post_i18n = PostI18nPeer::retrieveByPk($this->post->getId(), $culture);
      
      if(!$post_i18n instanceof PostI18n)
      {
        $post_i18n = new PostI18n();
      }
      
      $post_i18n->setPost($this->post);
      $this->post->setCulture($culture);      
      $this->post->setTitle($i18n['title']);      
      $this->post->setContent($i18n['content']); 
      $this->post->save();
    }       
  }
  
  protected function setTags($tag_phrase)
  {   
    if($this->post->getTagPhrase() === $tag_phrase)
    {
      return true;
    }
    
	  $updated_tags = array();
	  
	  // split phrase and put tags in the array
	  $handles = myTools::splitPhrase( $tag_phrase );
	      
    foreach($this->post->getPostTags() as $post_tag)
    {
      $existing_ids[] = $post_tag->getTagId();
    }
	  
	  foreach( $handles as $handle )
	  {
		  $tag = TagPeer::retrieveByHandle($handle);
      
		  // if tag does not exist in the db write it
		  if(!$tag instanceof Tag)
		  {	        
		    $tag = new Tag();
		    $tag->setHandle($handle);
        $tag->setCulture('en_US');
        $tag->setName(ucfirst($handle));
		    $tag->save();	    
		  }
		  
		  // if tag is not already linked to this post link it
		  if(!in_array($tag->getId(), $existing_ids))
		  {			  
		    $post_tag = new PostTag();
		    $post_tag->setPostId($this->post->getId());
		    $post_tag->setTagId($tag->getId());
		    $post_tag->save();		    
		  }
		 
		  $updated_tags[] = $tag->getId();
		  
	  }
	  
	  // find out if some tags were removed from the post and remove the post_tag record	  
	  foreach($existing_ids as $id)
	  {
	    if(!in_array($id, $updated_tags))
	    {
	      $c = new Criteria();
	      $c->add(PostTagPeer::POST_ID , $this->post->getId());
	      $c->add(PostTagPeer::TAG_ID , $id);
	      PostTagPeer::doDelete($c);
	    }
	  }
  }

  protected function getPostOrCreate($id = 'id')
  {
    if (!$this->getRequestParameter($id))
    {
      $post = new Post();
    }
    else
    {
      $post = PostPeer::retrieveByPk($this->getRequestParameter($id));

      $this->forward404Unless($post);
    }

    return $post;
  }

  protected function processFilters()
  {
    if ($this->getRequest()->hasParameter('filter'))
    {
      $filters = $this->getRequestParameter('filters');
      if (isset($filters['datetime']['from']) && $filters['datetime']['from'] !== '')
      {
        $filters['datetime']['from'] = sfI18N::getTimestampForCulture($filters['datetime']['from'], $this->getUser()->getCulture());
      }
      if (isset($filters['datetime']['to']) && $filters['datetime']['to'] !== '')
      {
        $filters['datetime']['to'] = sfI18N::getTimestampForCulture($filters['datetime']['to'], $this->getUser()->getCulture());
      }

      $this->getUser()->getAttributeHolder()->removeNamespace('sf_admin/post/filters');
      $this->getUser()->getAttributeHolder()->add($filters, 'sf_admin/post/filters');
    }
  }

  protected function processSort()
  {
    if ($this->getRequestParameter('sort'))
    {
      $this->getUser()->setAttribute('sort', $this->getRequestParameter('sort'), 'sf_admin/post/sort');
      $this->getUser()->setAttribute('type', $this->getRequestParameter('type', 'asc'), 'sf_admin/post/sort');
    }

    if (!$this->getUser()->getAttribute('sort', null, 'sf_admin/post/sort'))
    {
    }
  }

  protected function addFiltersCriteria($c)
  {
    if (isset($this->filters['handle_is_empty']))
    {
      $criterion = $c->getNewCriterion(PostPeer::HANDLE, '');
      $criterion->addOr($c->getNewCriterion(PostPeer::HANDLE, null, Criteria::ISNULL));
      $c->add($criterion);
    }
    else if (isset($this->filters['handle']) && $this->filters['handle'] !== '')
    {
      $c->add(PostPeer::HANDLE, strtr($this->filters['handle'], '*', '%'), Criteria::LIKE);
    }
    if (isset($this->filters['datetime_is_empty']))
    {
      $criterion = $c->getNewCriterion(PostPeer::DATETIME, '');
      $criterion->addOr($c->getNewCriterion(PostPeer::DATETIME, null, Criteria::ISNULL));
      $c->add($criterion);
    }
    else if (isset($this->filters['datetime']))
    {
      if (isset($this->filters['datetime']['from']) && $this->filters['datetime']['from'] !== '')
      {
        $criterion = $c->getNewCriterion(PostPeer::DATETIME, date('Y-m-d', $this->filters['datetime']['from']), Criteria::GREATER_EQUAL);
      }
      if (isset($this->filters['datetime']['to']) && $this->filters['datetime']['to'] !== '')
      {
        if (isset($criterion))
        {
          $criterion->addAnd($c->getNewCriterion(PostPeer::DATETIME, date('Y-m-d', $this->filters['datetime']['to']), Criteria::LESS_EQUAL));
        }
        else
        {
          $criterion = $c->getNewCriterion(PostPeer::DATETIME, date('Y-m-d', $this->filters['datetime']['to']), Criteria::LESS_EQUAL);
        }
      }

      if (isset($criterion))
      {
        $c->add($criterion);
      }
    }
    if (isset($this->filters['published_is_empty']))
    {
      $criterion = $c->getNewCriterion(PostPeer::PUBLISHED, '');
      $criterion->addOr($c->getNewCriterion(PostPeer::PUBLISHED, null, Criteria::ISNULL));
      $c->add($criterion);
    }
    else if (isset($this->filters['published']) && $this->filters['published'] !== '')
    {
      $c->add(PostPeer::PUBLISHED, $this->filters['published']);
    }
  }

  protected function addSortCriteria($c)
  {
    if ($sort_column = $this->getUser()->getAttribute('sort', null, 'sf_admin/post/sort'))
    {
      $sort_column = PostPeer::translateFieldName($sort_column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME);
      if ($this->getUser()->getAttribute('type', null, 'sf_admin/post/sort') == 'asc')
      {
        $c->addAscendingOrderByColumn($sort_column);
      }
      else
      {
        $c->addDescendingOrderByColumn($sort_column);
      }
    }
  }

  protected function getLabels()
  {
    return array(
      'post{handle}' => 'Handle:',
      'post{datetime}' => 'Datetime:',
      'post{published}' => 'Published:',
      'post{images}' => 'Images:',
      'post{i18n}' => 'I18n:', 
      'post{tags}' => 'Tags:',
    );
  }
  
  public function executeTags()
  {
    $post = $this->getRequestParameter('post');
    $tag = $post['tags'];

    $c = new Criteria();
    $c->add(TagPeer::HANDLE, $tag.'%', Criteria::LIKE);
    $this->options = TagPeer::doSelect($c);
  }
  
  public function executeHandle()
  {
  	$post = $this->getRequestParameter('post');
  	$title = $post['i18n'][sfConfig::get('sf_i18n_default_culture')]['title'];
  	$this->handle = myTools::makeHandle($title);
  }
  public function executeUnique()
  {
  	$params = $this->getRequestParameter('post');
  	$handle = $params['handle'];
  	$id = $this->getRequestParameter('id');
  	
    if (!$handle)
    {
      return sfView::NONE;  
    }
    
    $post = PostPeer::retrieveByHandle($handle);
    
    if (($post instanceof Answer) and ($post->getId() != $id))
    {
      return $this->renderText('<span class="error-message">'.sfContext::getInstance()->getI18N()->__('Not unique').'</span>');
    }
    else
    {
      return $this->renderText('<span class="success-message">'.sfContext::getInstance()->getI18N()->__('Unique').'</span>');
    }
  }
}
